package com.example.pacs.service.impl;

import com.example.pacs.bean.entity.*;
import com.example.pacs.dao.*;
import com.example.pacs.dicom.server.cstoresup.DicomReader;
import com.example.pacs.enums.PacsExceptionEnum;
import com.example.pacs.exception.PacsException;
import com.example.pacs.service.PatientService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;

@Service
@Slf4j
public class PatientServiceImpl implements PatientService {

    @Resource
    private PatientMapper patientMapper;

    @Resource
    private StudyMapper studyMapper;

    @Resource
    private SeriesMapper seriesMapper;

    @Resource
    private EquipmentMapper equipmentMapper;

    @Resource
    private InstanceMapper instanceMapper;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void insertAllPatientInfo(DicomReader dicomReader) {
        try {
            Patient patient = buildPatient(dicomReader);
            Study study = buildStudy(dicomReader, patient.getId());
            Series series = buildSeries(dicomReader, study.getId());
            buildEquipment(dicomReader, series.getId());
            Instance instance = buildInstance(dicomReader, series.getId());
            log.info("dcm信息入库成功,instance:{}", instance.toString());
        } catch (Exception e) {
            log.error("入库dcm信息异常!dicomReader:" + dicomReader.toString() + "_异常信息:" + e.getMessage(), e);
            throw new PacsException(PacsExceptionEnum.INSERT_DCM_MESSAGE_ERROR);
        }
    }

    /**
     * 入库患者基本信息
     */
    private Patient buildPatient(DicomReader dicomReader) {
        // 根据患者ID查询患者是否存在
        Patient patient = patientMapper.queryPatientByPatientId(dicomReader.getPatientId());
        if (patient == null) {
            patient = new Patient();
            patient.setPatientId(dicomReader.getPatientId());
            patient.setPatientAge(dicomReader.getPatientAge());
            patient.setPatientSex(dicomReader.getPatientSex());
            patient.setPatientName(dicomReader.getPatientName());
            patient.setPatientBirthday(dicomReader.getPatientBirthday());
            patient.setCreatedDate(new Date());
            patient.setModifiedDate(new Date());
            patientMapper.insertSelective(patient);
            patient = patientMapper.queryPatientByPatientId(dicomReader.getPatientId());
        } else {
            log.info("患者:{}已存在", patient.getPatientName());
        }
        return patient;
    }

    /**
     * 入库study
     *
     * @param dicomReader 元数据
     * @param patientPrimary 患者表主键
     * @return study
     */
    private Study buildStudy(DicomReader dicomReader, Long patientPrimary) {
        // 根据studyInstanceUid查询study是否存在
        Study study = studyMapper.queryStudyByStudyInstanceUid(dicomReader.getStudyInstanceUID());
        if (study == null) {
            study = new Study();
            study.setStudyId(dicomReader.getStudyID());
            study.setAccessionNumber(dicomReader.getAccessionNumber());
            study.setPatientId(patientPrimary);
            study.setStudyStatusId(dicomReader.getStudyStatusID());
            study.setStudyDescription(dicomReader.getStudyDescription());
            study.setAdditionalPatientHistory(dicomReader.getAdditionalPatientHistory());
            study.setReferringPhysicianName(dicomReader.getReferringPhysicianName());
            study.setStudyInstanceUid(dicomReader.getStudyInstanceUID());
            study.setStudyDateTime(dicomReader.getStudyDateTime());
            studyMapper.insertSelective(study);
            study = studyMapper.queryStudyByStudyInstanceUid(dicomReader.getStudyInstanceUID());
        } else {
            log.info("该{}study已经存在!", study.getStudyInstanceUid());
        }
        return study;
    }

    /**
     * 入库series信息
     *
     * @param dicomReader 元数据
     * @param studyPrimary study主键
     * @return series
     */
    public Series buildSeries(DicomReader dicomReader, Long studyPrimary) {
        // 根据seriesInstanceUid和seriesNumber查询series是否存在
        Series series = seriesMapper.querySeriesBySeriesInstanceIdAndSeriesNumber(dicomReader.getSeriesInstanceUID(), dicomReader.getSeriesNumber());
        if (series == null) {
            series = new Series();
            series.setLaterality(dicomReader.getLaterality());
            series.setBodyPartExamined(dicomReader.getBodyPartExamined());
            series.setOperatorsName(dicomReader.getOperatorsName());
            series.setPatientPosition(dicomReader.getPatientPosition());
            series.setProtocolName(dicomReader.getProtocolName());
            series.setSeriesDateTime(dicomReader.getSeriesDateTime());
            series.setSeriesDescription(dicomReader.getSeriesDescription());
            series.setSeriesInstanceUid(dicomReader.getSeriesInstanceUID());
            series.setSeriesNumber(dicomReader.getSeriesNumber());
            series.setStudyId(studyPrimary);
            series.setCreatedDate(new Date());
            series.setModifiedDate(new Date());
            seriesMapper.insertSelective(series);
            series = seriesMapper.querySeriesBySeriesInstanceIdAndSeriesNumber(dicomReader.getSeriesInstanceUID(), dicomReader.getSeriesNumber());
        } else {
            log.info("该seriesInstanceUid:{},seriesNumber:{}series已经存在", series.getSeriesInstanceUid(), series.getSeriesNumber());
        }
        return series;
    }

    /**
     * 入库设备信息
     *
     * @param dicomReader 元数据
     * @param seriesPrimary series主键
     */
    private void buildEquipment(DicomReader dicomReader, Long seriesPrimary) {
        // 根据series主键查询设备是否存在
        Equipment equipment = equipmentMapper.queryEquipmentBySeriesPrimary(seriesPrimary);
        if (equipment == null) {
            equipment = new Equipment();
            equipment.setConversionType(dicomReader.getConversionType());
            equipment.setDeviceSerialNumber(dicomReader.getDeviceSerialNumber());
            equipment.setInstitutionAddress(dicomReader.getInstitutionAddress());
            equipment.setInstitutionName(dicomReader.getInstitutionName());
            equipment.setInstitutionalDepartmentName(dicomReader.getInstitutionalDepartmentName());
            equipment.setManufacturer(dicomReader.getManufacturer());
            equipment.setManufacturerModelName(dicomReader.getManufacturerModelName());
            equipment.setSeriesId(seriesPrimary);
            equipment.setSoftwareVersion(dicomReader.getSoftwareVersion());
            equipment.setStationName(dicomReader.getStationName());
            equipment.setCreatedDate(new Date());
            equipment.setModifiedDate(new Date());
            equipment.setModality(dicomReader.getModality());
            equipmentMapper.insertSelective(equipment);
        } else {
            log.error("该{}equipment已经存在!", equipment.getId());
        }
    }

    /**
     * 入库instance信息
     *
     * @param dicomReader 元数据
     * @param seriesPrimary series主键
     * @return 实例
     */
    private Instance buildInstance(DicomReader dicomReader, Long seriesPrimary) {
        // 根据SOPInstanceUid查询instance是否存在
        Instance instance = instanceMapper.queryInstanceBySopInstanceUid(dicomReader.getSOPInstanceUID());
        if (instance == null) {
            instance = new Instance();
            instance.setInstanceNumber(dicomReader.getInstanceNumber());
            instance.setAcquisitionDateTime(dicomReader.getAcquisitionDateTime());
            instance.setContentDateTime(dicomReader.getContentDateTime());
            instance.setSopInstanceUid(dicomReader.getSOPInstanceUID());
            instance.setAcquisitionDateTime(dicomReader.getAcquisitionDateTime());
            instance.setExposureTime(dicomReader.getExposureTime());
            instance.setImageOrientation(dicomReader.getImageOrientation());
            instance.setImagePosition(dicomReader.getImagePosition());
            instance.setImageType(dicomReader.getImageType());
            instance.setKvp(dicomReader.getKvp());
            instance.setMediaStorageSopInstanceUid(dicomReader.getMediaStorageSopInstanceUID());
            instance.setPixelSpacing(dicomReader.getPixelSpacing());
            instance.setSliceLocation(dicomReader.getSliceLocation());
            instance.setSeriesId(seriesPrimary);
            instance.setSliceThickness(dicomReader.getSliceThickness());
            instance.setSopClassUid(dicomReader.getSopClassUID());
            instance.setTransferSyntaxUid(dicomReader.getTransferSyntaxUID());
            instance.setWindowCenter(dicomReader.getWindowCenter());
            instance.setWindowWidth(dicomReader.getWindowWidth());
            instance.setXrayTubeCurrent(dicomReader.getXrayTubeCurrent());
            instance.setPatientOrientation(dicomReader.getPatientOrientation());
            instance.setCreatedDate(new Date());
            instance.setModifiedDate(new Date());
            instanceMapper.insertSelective(instance);
            instance = instanceMapper.queryInstanceBySopInstanceUid(dicomReader.getSOPInstanceUID());
        } else {
            log.info("该{}instance已经存在!", instance.getId());
        }
        return instance;
    }
}
